#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bd.h"

//largo maximo esperado paara una linea en los archivos
#define MAXTEMP 501

nodo_producto * prod_inicial=NULL,*prod_final=NULL;
nodo_usuario * usr_inicial=NULL,*usr_final=NULL;
nodo_producto nulo={"","","",0,0,{0,0},{0,0},{0,0},{0,0},{0,0},0,0,0,0,0,0};
int nprods, nusrs;

static nodo_producto * leerStructProd(FILE * archivo);
static nodo_usuario * leerStructUsr(FILE * archivo);
static int guardarBDUsr(char *usuarios,nodo_usuario * lista);
static int guardarBDProd(char *productos,nodo_producto * lista);
static nodo_producto * cargarProductos(char *archivo);
static nodo_usuario * cargarUsuarios(char *usuarios);
static int contarElementosP(nodo_producto * prod,int aux);
static char * mistrtok(char * str1,char token);

void inicializarBd(nodo_usuario **usuarios,nodo_producto **productos)
{
    if(!usr_inicial)
        usr_inicial=cargarUsuarios(FUSUARIOS);
    if(!prod_final)
        prod_inicial=cargarProductos(FPRODUCTOS);
    if(usuarios)
        *usuarios=usr_inicial;
    if(productos)
        *productos=prod_inicial;
}

int cerrarBd(void)
{
    int i;
    i=guardarBDProd(FPRODUCTOS,prod_inicial) | guardarBDUsr(FUSUARIOS,usr_inicial);
    liberarListaP(prod_inicial);
    liberarListaU(usr_inicial);
    prod_inicial=NULL;
    usr_inicial=NULL;
    prod_final=NULL;
    usr_final=NULL;
    return i;
}

void guardarBD(void)
{
    guardarBDProd(FPRODUCTOS,prod_inicial);
    guardarBDUsr(FUSUARIOS,usr_inicial);
}

nodo_producto * cargarProductos(char *productos)
{
    nodo_producto *temp=NULL,*anterior;
    FILE * archivo=NULL;
    int i=0;
    if(prod_inicial)
        return prod_inicial;
    else
    {
        if((archivo=fopen(productos,"r")))
        {
            do
            {
                if(!prod_inicial)
                {
                    if((int)(prod_inicial=leerStructProd(archivo))==-1)
                        return prod_inicial;
                    prod_final=prod_inicial;
                    anterior=prod_inicial;
                    if(prod_inicial)
                    {
                        prod_inicial->ant=NULL;
                        i++;
                    }
                }
                else
                {
                    anterior=prod_final;
                    prod_final->sig=temp;
                    prod_final=prod_final->sig;
                    prod_final->ant=anterior;
                    i++;
                }
                if((int)(temp=leerStructProd(archivo))==-1)
                    return temp;
            }
            while(temp!=NULL);
            if(prod_final)
                prod_final->sig=(nodo_producto *)NULL;
            fclose(archivo);
            nprods=i;
            return prod_inicial;
        }
        else return (nodo_producto *) NULL;
    }
}

static nodo_producto * leerStructProd(FILE * archivo)
{
    char buffer[MAXTEMP];
    nodo_producto * temp;
    char * temp2;
    if(fgets(buffer,sizeof(buffer),archivo))
    {
        if((temp=(nodo_producto *) malloc(sizeof(nodo_producto)))!=NULL)
        {
            if((temp->nombre=mistrtok(buffer,';'))==NULL)
            {
                free(temp);
                return (nodo_producto *)-1;
            }
            if((temp->descripcion=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_producto *)-1;
            }
            if((temp->codigo=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_producto *)-1;
            }
            if((temp2=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_producto *)-1;
            }
            temp->precio=atoi(temp2);
            free(temp2);
            if((temp2=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_producto *)-1;
            }
            temp->stock=atoi(temp2);
            free(temp2);
            if((temp2=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_producto *)-1;
            }
            temp->dia.t=atoi(temp2);
            free(temp2);
            if((temp2=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_producto *)-1;
            }
            temp->dia.dato=atoi(temp2);
            free(temp2);
            if((temp2=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_producto *)-1;
            }
            temp->semana.t=atoi(temp2);
            free(temp2);
            if((temp2=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_producto *)-1;
            }
            temp->semana.dato=atoi(temp2);
            free(temp2);
            if((temp2=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_producto *)-1;
            }
            temp->mes_act.t=atoi(temp2);
            free(temp2);
            if((temp2=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_producto *)-1;
            }
            temp->mes_act.dato=atoi(temp2);
            free(temp2);
            if((temp2=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_producto *)-1;
            }
            temp->mes_ant.t=atoi(temp2);
            free(temp2);
            if((temp2=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_producto *)-1;
            }
            temp->mes_ant.dato=atoi(temp2);
            free(temp2);
            if((temp2=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_producto *)-1;
            }
            temp->mes_ant2.t=atoi(temp2);
            free(temp2);
            if((temp2=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_producto *)-1;
            }
            temp->mes_ant2.dato=atoi(temp2);
            free(temp2);
            if((temp2=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_producto *)-1;
            }
            temp->total=atoi(temp2);
            free(temp2);
            if((temp2=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_producto *)-1;
            }
            temp->compra=atoi(temp2);
            free(temp2);
            return temp;
        }
        else return (nodo_producto *)-1;
    }
    else return (nodo_producto *) NULL;
}

int guardarBDProd(char *productos,nodo_producto * lista)
{
    FILE * archivo;
    if((archivo=fopen(productos,"w")))
    {
        while(lista)
        {
            fprintf(archivo,"%s;%s;%s;%i;%i;",lista->nombre,lista->descripcion,lista->codigo,lista->precio,lista->stock);
            fprintf(archivo,"%i;%i;%i;%i;%i;",lista->dia.t,lista->dia.dato,lista->semana.t,lista->semana.dato,lista->mes_act.t);
            fprintf(archivo,"%i;%i;%i;%i;%i;",lista->mes_act.dato,lista->mes_ant.t,lista->mes_ant.dato,lista->mes_ant2.t,
                    lista->mes_ant2.dato);
            fprintf(archivo,"%i;%i",lista->total,lista->compra);
            lista=lista->sig;
            if(lista)
            {
                fprintf(archivo,"\n");
            }
        }
        fclose(archivo);
        return 0;
    }
    else return 2;
}

void agregarProd(nodo_producto * nuevo)
{
    nuevo->ant=NULL;
    if(prod_inicial)
    {
        prod_final->sig=nuevo;
        nuevo->ant=prod_final;
    }
    else prod_inicial=nuevo;
    nuevo->sig=(nodo_producto *) NULL;
    prod_final=nuevo;
    nprods++;
}

void liberarListaP(nodo_producto * inicio)
{
    nodo_producto *temp;
    while(inicio!=NULL)
    {
        temp=inicio->sig;
        liberarStructP(inicio);
        inicio=temp;
    }
}

void liberarStructP(nodo_producto * estructura)
{
    if(estructura)
    {
        free(estructura->nombre);
        free(estructura->descripcion);
        free(estructura->codigo);
        free(estructura);
    }
}

void liberarListaU(nodo_usuario * inicio)
{
    nodo_usuario *temp;
    while(inicio!=NULL)
    {
        temp=inicio->sig;
        liberarStructU(inicio);
        inicio=temp;
    }
}

void liberarStructU(nodo_usuario * estructura)
{
    if(estructura)
    {
        free(estructura->nombre);
        free(estructura);
    }
}

nodo_usuario * cargarUsuarios(char *usuarios)
{
    FILE *archivo;
    int i=0;
    if((archivo=fopen(usuarios,"r")))
    {
        nodo_usuario *temp=NULL,*anterior;
        do
        {
            if(!usr_inicial)
            {
                if((int)(usr_inicial=leerStructUsr(archivo))==-1)
                    return (nodo_usuario *)-1;
                usr_final=usr_inicial;
                if(usr_final)
                {
                    usr_final->ant=NULL;
                    i++;
                }
            }
            else
            {
                anterior=usr_final;
                usr_final->sig=temp;
                usr_final=usr_final->sig;
                usr_final->ant=anterior;
                i++;
            }
            if((int)(temp=leerStructUsr(archivo))==-1)
                return (nodo_usuario *)-1;
        }
        while(temp!=NULL);
        if(usr_final)
            usr_final->sig=(nodo_usuario *)NULL;
        fclose(archivo);
        nusrs=i;
        return usr_inicial;
    }
    else return (nodo_usuario *) NULL;
}

static nodo_usuario * leerStructUsr(FILE * archivo)
{
    nodo_usuario * temp;
    char * temp2;
    char buffer[MAXTEMP];
    if(fgets(buffer,sizeof(buffer),archivo))
    {
        if((temp=(nodo_usuario *) malloc(sizeof(nodo_usuario)))!=NULL)
        {
            if((temp->nombre=mistrtok(buffer,';'))==NULL)
            {
                free(temp);
                return (nodo_usuario *)NULL;
            }
            if((temp2=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_usuario *)-1;
            }
            temp->id=atoi(temp2);
            free(temp2);
            if((temp2=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_usuario *)-1;
            }
            temp->dia.t=atoi(temp2);
            free(temp2);
            if((temp2=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_usuario *)-1;
            }
            temp->dia.dato=atoi(temp2);
            free(temp2);
            if((temp2=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_usuario *)-1;
            }
            temp->semana.t=atoi(temp2);
            free(temp2);
            if((temp2=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_usuario *)-1;
            }
            temp->semana.dato=atoi(temp2);
            free(temp2);
            if((temp2=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_usuario *)-1;
            }
            temp->mes_act.t=atoi(temp2);
            free(temp2);
            if((temp2=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_usuario *)-1;
            }
            temp->mes_act.dato=atoi(temp2);
            free(temp2);
            if((temp2=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_usuario *)-1;
            }
            temp->mes_ant.t=atoi(temp2);
            free(temp2);
            if((temp2=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_usuario *)-1;
            }
            temp->mes_ant.dato=atoi(temp2);
            free(temp2);
//
            if((temp2=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_usuario *)-1;
            }
            temp->mes_ant2.t=atoi(temp2);
            free(temp2);
            if((temp2=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_usuario *)-1;
            }
            temp->mes_ant2.dato=atoi(temp2);
            free(temp2);
            if((temp2=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_usuario *)-1;
            }
            temp->total=atoi(temp2);
            free(temp2);
            if((temp->pass=mistrtok(NULL,';'))==NULL)
            {
                free(temp);
                return (nodo_usuario *)-1;
            }
            return temp;
        }
        else return (nodo_usuario *)-1;
    }
    else return (nodo_usuario *) NULL;
}

int guardarBDUsr(char * usuarios,nodo_usuario * lista)
{
    FILE * archivo=NULL;
    if((archivo=fopen(usuarios,"w")))
    {
        while(lista)
        {
            fprintf(archivo,"%s;%i;%i;%i;%i;%i;",lista->nombre, lista->id, lista->dia.t, lista->dia.dato,
                    lista->semana.t, lista->semana.dato);
            fprintf(archivo,"%i;%i;%i;%i;%i;%i;%i;%s",lista->mes_act.t, lista->mes_act.dato,0,0,0,0,lista->total,lista->pass);
            lista=lista->sig;
            if(lista)
            {
                fprintf(archivo,"\n");
            }
        }
        fclose(archivo);
        return 0;
    }
    else return 1;
}

void agregarUsr(nodo_usuario * nuevo)
{
    nuevo->ant=NULL;
    if(usr_inicial)
    {
        usr_final->sig=nuevo;
        nuevo->ant=usr_final;
    }
    else usr_inicial=nuevo;
    nuevo->sig=(nodo_usuario *) NULL;
    usr_final=nuevo;
    nusrs++;
}

res_busq_p * buscarProd(nodo_producto * filtro,int tipo)
{
    res_busq_p * resultado=NULL,*temp_res=NULL,*temp2_res=NULL,*anterior=NULL;
    nodo_producto * temp=prod_inicial;
    int st;
    while(temp)
    {
        switch(tipo)
        {
        case 0:
        default:
            st=(temp->stock>=filtro->stock);
            break;
        case 1:
            st=(temp->stock<=filtro->stock);
            break;
        case 2:
            st=(temp->stock==filtro->stock);
        }
        if((contenida(temp->nombre,filtro->nombre,tipo))&&(contenida(temp->descripcion,filtro->descripcion,tipo))&&(contenida(temp->codigo,filtro->codigo,tipo))&&st)
        {
            temp_res=(res_busq_p *) malloc(sizeof(res_busq_p));
            temp_res->prod=temp;
            if(resultado==NULL)
            {
                resultado=temp_res;
                temp2_res=resultado;
                resultado->ant=NULL;
            }
            else
            {
                temp2_res->sig=temp_res;
                temp2_res=temp2_res->sig;
                temp2_res->ant=anterior;
            }
            anterior=temp2_res;
        }
        temp=temp->sig;
    }
    if(temp2_res)
        temp2_res->sig=NULL;
    return resultado;
}

//tipo1: criterio comparacion entre filtros, tipo2: todos los miembros cumplen tipo1 o solo algunos
nodo_producto * buscarProd2(nodo_producto * filtro,int cmp, int y)
{
    nodo_producto * resultado=NULL,*res_temp=NULL,*anterior=NULL;
    nodo_producto * temp=prod_inicial; //temp va avanzando
    int st;
    while(temp)
    {
        //con stock -1, quiero que stock no influya en el resultado..., si stock=-1 y: y=0 , st debe ser 0
        //asi no cambia nada en el OR y si y=1 st=1 para no afectar el AND
        if(filtro->stock==-1)
            st=y?1:0;
        else switch(cmp)
            {
            case 0:
            default:
                st=(temp->stock>=filtro->stock);
                break;
            case 1:
                st=(temp->stock<=filtro->stock);
                break;
            case 2:
                st=(temp->stock==filtro->stock);
            }
        if(y)
            st&=(contenida(temp->nombre,filtro->nombre,cmp))&&
                (contenida(temp->descripcion,filtro->descripcion,cmp))&&(contenida(temp->codigo,filtro->codigo,cmp));
        else st|=(contenida(temp->nombre,filtro->nombre,cmp))||(contenida(temp->descripcion,filtro->descripcion,cmp))
                     ||(contenida(temp->codigo,filtro->codigo,cmp));
        if(st)
        {
            if(resultado==NULL)
            {
                resultado=temp;
                res_temp=resultado;
                resultado->ant2=NULL;
            }
            else
            {
                res_temp->sig2=temp;
                res_temp=res_temp->sig2;
                res_temp->ant2=anterior;
            }
            anterior=res_temp;
        }
        temp=temp->sig;
    }
    if(res_temp)
        res_temp->sig2=NULL;
    return resultado;
}

int contenida(const char * palabra,const char * test,int tipo)
{
    int retorno;
    if(test!=NULL&&*test!='\0')
    {
        switch(tipo)
        {
        case 0: //contine la cadena, en cualquier posicion!!,si test tiene longitud cero, devueve 1
        default:
            retorno=(strstr(palabra,test)!=NULL);
            break;
        case 1: //
            retorno=(strstr(palabra,test)==palabra);//si palabra empieza con test
            break;
        case 2:
            retorno=(strcmp(palabra,test)==0);//si palabra=test
            break;
        }
    }
    else retorno=1;
    return retorno;
}

void borrarProducto(nodo_producto * nodo)
{
    if(nodo->ant) //si no es el primer elemento
        (nodo->ant)->sig=nodo->sig;
    else prod_inicial=nodo->sig;
    if(nodo->sig) //si no es el ultimo
        (nodo->sig)->ant=nodo->ant;
    else prod_final=nodo->ant;
    nprods--;
    liberarStructP(nodo);
}

nodo_usuario * buscarUsr2(nodo_usuario * filtro,int tipo)
{
    nodo_usuario * resultado=NULL,*res_temp=NULL,*anterior=NULL;
    nodo_usuario * temp=usr_inicial;
    while(temp)
    {
        if(contenida(temp->nombre,filtro->nombre,tipo)&&contenida(temp->pass,filtro->pass,tipo))
        {
            if(resultado==NULL)
            {
                resultado=temp;
                res_temp=temp;
                anterior=temp;
                resultado->ant2=NULL;
            }
            else
            {
                res_temp->sig2=temp;
                res_temp=temp;
                res_temp->ant2=anterior;
            }
            anterior=temp;
        }
        temp=temp->sig;
    }
    if(res_temp)
        res_temp->sig2=NULL;
    return resultado;
}

res_busq_u * buscarUsr(nodo_usuario * filtro,int tipo)
{
    res_busq_u * resultado=NULL,*temp_res=NULL,*temp2_res=NULL;
    nodo_usuario * temp=usr_inicial;
    while(temp)
    {
        if(contenida(temp->nombre,filtro->nombre,tipo))
        {
            temp_res=(res_busq_u *) malloc(sizeof(res_busq_u));
            temp_res->usr=temp;
            if(resultado==NULL)
            {
                resultado=temp_res;
                temp2_res=temp_res;
            }
            else
            {
                temp2_res->sig=temp_res;
                temp2_res=temp2_res->sig;
            }
        }
        temp=temp->sig;
    }
    if(temp2_res)
        temp2_res->sig=NULL;
    return resultado;
}

void borrarUsuario(nodo_usuario * nodo)
{
    if(nodo->ant)
        (nodo->ant)->sig=nodo->sig;
    else
        usr_inicial=nodo->sig;
    if(nodo->sig)
        (nodo->sig)->ant=nodo->ant;
    else
        usr_final=nodo->ant;
    nusrs--;
    liberarStructU(nodo);
}

void liberarResBusqP(res_busq_p * nodo)
{
    res_busq_p *temp;
    while(nodo)
    {
        temp=nodo->sig;
        free(nodo);
        nodo=temp;
    }
}

void liberarResBusqU(res_busq_u * nodo)
{
    res_busq_u *temp;
    while(nodo)
    {
        temp=nodo->sig;
        free(nodo);
        nodo=temp;
    }
}

void obtNumPU(int * usuarios, int * productos)
{
    *usuarios=nusrs;
    *productos=nprods;
}

//si aux=1, la lista se devuelve ordenada en los punteros ant2 y sig2
nodo_producto * ordenarListaP(nodo_producto * lista,int (*comp)(const void * nodo1,const void * nodo2),int aux)
{
    int i,num=nprods;//contarElementosP(prod_inicial);
    nodo_producto *temp2,** temp=(nodo_producto **)malloc(num*sizeof(nodo_producto *));
    temp2=prod_inicial;
    if(lista)
    {   temp2=lista;
        num=contarElementosP(lista,1);
    }
    if(aux&&lista)
        for(i=0; i<num; temp[i]=temp2,temp2=temp2->sig2,i++);
    else for(i=0; i<num; temp[i]=temp2,temp2=temp2->sig,i++);
    qsort(temp,num,sizeof(nodo_producto*),comp);
    if(aux==0&&lista==NULL)
    {
        for(i=0; i<(num-1); i++)
        {
            temp[i]->sig=temp[i+1];
            if(i>0)
                temp[i]->ant=temp[i-1];
        }
        temp[0]->ant=NULL;
        temp[num-1]->sig=NULL;
        temp[num-1]->ant=temp[num-2];
        prod_inicial=temp[0];
        prod_final=temp[num-1];
        return prod_inicial;
    }else
    {
        for(i=0; i<(num-1); i++)
        {
            temp[i]->sig2=temp[i+1];
            if(i>0)
                temp[i]->ant2=temp[i-1];
        }
        temp[0]->ant2=NULL;
        temp[num-1]->sig2=NULL;
        if(num>1)
            temp[num-1]->ant2=temp[num-2];
        prodAuxInicial=temp[0];
        return prodAuxInicial;
    }
}

int compProdNomAZ(const void * nodo1,const void * nodo2)
{
    return strcmp((*(nodo_producto **)nodo1)->nombre,(*(nodo_producto **)nodo2)->nombre);
}

int compProdNomZA(const void * nodo1,const void * nodo2)
{
    return strcmp((*(nodo_producto **)nodo2)->nombre,(*(nodo_producto**)nodo1)->nombre);
}

int compProdPrecioDes(const void * nodo1,const void * nodo2)
{
    return (*(nodo_producto **)nodo2)->precio-(*(nodo_producto**)nodo1)->precio;
}

int compProdPrecioAs(const void * nodo1,const void * nodo2)
{
    return (*(nodo_producto **)nodo1)->precio-(*(nodo_producto **)nodo2)->precio;
}

int compProdStockDes(const void * nodo1,const void * nodo2)
{
    return (*(nodo_producto**)nodo2)->stock-(*(nodo_producto**)nodo1)->stock;
}

int compProdStockAs(const void * nodo1,const void * nodo2)
{
    return (*(nodo_producto **)nodo1)->stock-(*(nodo_producto**)nodo2)->stock;
}

int compProdCodAZ(const void * nodo1,const void * nodo2)
{
    return strcmp((*(nodo_producto **)nodo2)->codigo,(*(nodo_producto **)nodo1)->codigo);
}

int compProdCodZA(const void * nodo1,const void * nodo2)
{
    return strcmp((*(nodo_producto **)nodo1)->codigo,(*(nodo_producto **)nodo2)->codigo);
}

int compProdVentMesAcAs(const void * nodo1,const void * nodo2)
{
    return (*(nodo_producto **)nodo1)->mes_act.dato-(*(nodo_producto **)nodo2)->mes_act.dato;
}

int compProdVentMesAntAs(const void * nodo1,const void * nodo2)
{
    return (*(nodo_producto **)nodo1)->mes_ant.dato-(*(nodo_producto **)nodo2)->mes_ant.dato;
}

int compProdVentMesAnt2As(const void * nodo1,const void * nodo2)
{
    return (*(nodo_producto **)nodo1)->mes_ant2.dato-(*(nodo_producto **)nodo2)->mes_ant2.dato;
}

int compProdVentTotalAs(const void * nodo1,const void * nodo2)
{
    return (*(nodo_producto **)nodo1)->total-(*(nodo_producto **)nodo2)->total;
}

int compProdVentSemanaAs(const void * nodo1,const void * nodo2)
{
    return (*(nodo_producto **)nodo1)->semana.dato-(*(nodo_producto **)nodo2)->semana.dato;
}

int compProdVentDiaAs(const void * nodo1,const void * nodo2)
{
    return (*(nodo_producto **)nodo1)->dia.dato-(*(nodo_producto **)nodo2)->dia.dato;
}

//
int compProdVentMesAcDes(const void * nodo1,const void * nodo2)
{
    return (*(nodo_producto **)nodo2)->mes_act.dato-(*(nodo_producto **)nodo1)->mes_act.dato;
}

int compProdVentMesAntDes(const void * nodo1,const void * nodo2)
{
    return (*(nodo_producto **)nodo2)->mes_ant.dato-(*(nodo_producto **)nodo1)->mes_ant.dato;
}

int compProdVentMesAnt2Des(const void * nodo1,const void * nodo2)
{
    return (*(nodo_producto **)nodo2)->mes_ant2.dato-(*(nodo_producto **)nodo1)->mes_ant2.dato;
}

int compProdVentTotalDes(const void * nodo1,const void * nodo2)
{
    return (*(nodo_producto **)nodo2)->total-(*(nodo_producto **)nodo1)->total;
}

int compProdVentSemanaDes(const void * nodo1,const void * nodo2)
{
    return (*(nodo_producto **)nodo2)->semana.dato-(*(nodo_producto **)nodo1)->semana.dato;
}

int compProdVentDiaDes(const void * nodo1,const void * nodo2)
{
    return (*(nodo_producto **)nodo2)->dia.dato-(*(nodo_producto **)nodo1)->dia.dato;
}

char * mistrtok(char * str1,char token)
{
    char * temp1;
    char * temp2;
    int i;
    static char * string;
    if(str1!=NULL)
        string=str1;
    temp1=string;
    if(string&&*string!=0&&*string!='\n')
    {
        while(string&&*string!=0&&*string!='\n'&&*string!=token)
            string++; //busco token
        temp2=(char *)malloc(sizeof(char)*(string-temp1+1));
        for(i=0; i<(string-temp1); i++)
            *(temp2+i)=*(temp1+i); //copio la cadena
        if(*string!=0) string++;
        *(temp2+i)=0;
    }
    else return NULL;
    return temp2;
}

nodo_producto * buscarProdFecha(FECHA * fecha,int mes)
{
    nodo_producto * resultado=NULL,*res_temp=NULL,*anterior=NULL;
    nodo_producto * temp=prod_inicial; //temp va avanzando
    int st;
    while(temp)
    {   st=1;
        if(fecha->dia!=-1)
            st=(fecha->dia==temp->dia.t);
        else
            if(fecha->semana!=-1)
                st=(fecha->semana==temp->semana.t);
        switch(mes)
            {
                case 0: //mes actual
                    st=st&&(fecha->mes==temp->mes_act.t);
                    break;
                case 1: //mes anterior
                    st=st&&((fecha->mes-1)==temp->mes_ant.t);
                    break;
                case 3:
                    st=st&&((fecha->mes-2)==temp->mes_ant2.t);
                    break;
            }
        if(st)
        {
            if(resultado==NULL)
            {
                resultado=temp;
                res_temp=resultado;
                resultado->ant2=NULL;
            }
            else
            {
                res_temp->sig2=temp;
                res_temp=res_temp->sig2;
                res_temp->ant2=anterior;
            }
            anterior=res_temp;
        }
        temp=temp->sig;
    }
    if(res_temp)
        res_temp->sig2=NULL;
    return resultado;
}

int contarElementosP(nodo_producto * prod,int aux)
{
    int i=0;
    if(aux)
        for(i;prod;prod=prod->sig2, i++);
    else
        for(i;prod;prod=prod->sig, i++);
    return i;
}
